﻿using AcadServices = Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

namespace _19对话框综合示例
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            this.DrawEentity();
        }

        //画图形的函数
        private void DrawEentity()
        {
            int width = picBxDrawMap.Width;
            int height = picBxDrawMap.Height;
            Bitmap bitmap = new Bitmap(width, height);//创建一个位图对象
            Graphics graph = Graphics.FromImage(bitmap); //通过位图创建GDI+对象
            Rectangle rect = new Rectangle((int)(width * 0.15), (int)(height * 0.15), (int)(width * 0.8), (int)(height * 0.8));


            //绘制图形
            MyEnttitys ents = new MyEnttitys((double)numUDlength.Value, (double)numUDheight.Value, (double)numUDRadius.Value);
            Rectangle rectExtends = this.DrawLineAndArc(bitmap, graph, rect,ents);
            //画注释
            this.DrawDimension(bitmap, graph, rectExtends,ents.Ents);
            //graph.DrawRectangle(new Pen(Brushes.Red), rect);
            picBxDrawMap.Image = bitmap;

        }
        //private Rectangle DrawLineAndArc(Bitmap bitmap, Graphics graph, Rectangle rect)
        //{
        //    double ratio = rect.Width * 1.0 / rect.Height;
        //    double width = (double)numUDlength.Value;//矩形宽度
        //    double height = (double)numUDheight.Value;//矩形的高度
        //    Pen pen = new Pen(Brushes.Black);
        //    Point topLineLeftPoint;
        //    Point topLineRightPoint;
        //    Point rightLineTopPoint;
        //    Point rightLineBottomPoint;
        //    Point bottomLineLeftPoint;
        //    Point bottomLineRightPoint;
        //    Point leftLineTopPoint;
        //    Point leftLineBottomPoint;
        //    if (width / height >= ratio)
        //    {
        //        //以长度占满绘图区域，按比例绘制高度，圆弧
        //        // width => rect.Width height = height * rect.Width/wdith
        //        height = height * rect.Width / width;
        //        int divHeight = (int)(rect.Height - height) / 2;
        //        topLineLeftPoint = new Point(rect.X, rect.Y + divHeight);
        //        topLineRightPoint = new Point(rect.X + rect.Width, rect.Y + divHeight);
        //        rightLineTopPoint = topLineRightPoint;
        //        rightLineBottomPoint = new Point(rect.X + rect.Width, rect.Y + rect.Height - divHeight);
        //        bottomLineLeftPoint = new Point(rect.X, rect.Y + rect.Height - divHeight);
        //        bottomLineRightPoint = rightLineBottomPoint;
        //        leftLineTopPoint = topLineLeftPoint;
        //        leftLineBottomPoint = bottomLineLeftPoint;
        //    }
        //    else
        //    {
        //        //以高度占满绘图区域，按比例绘制长度，圆弧
        //        width = width * rect.Height / height;
        //        int divWidth = (int)(rect.Width - width) / 2;
        //        topLineLeftPoint = new Point(rect.X + divWidth, rect.Y);
        //        topLineRightPoint = new Point(rect.X + rect.Width - divWidth, rect.Y);
        //        rightLineTopPoint = topLineRightPoint;
        //        rightLineBottomPoint = new Point(rect.X + rect.Width - divWidth, rect.Y + rect.Height);
        //        bottomLineLeftPoint = new Point(rect.X + divWidth, rect.Y + rect.Height);
        //        bottomLineRightPoint = rightLineBottomPoint;
        //        leftLineTopPoint = topLineLeftPoint;
        //        leftLineBottomPoint = bottomLineLeftPoint;

        //    }
        //    //绘制上边线
        //    graph.DrawLine(pen, topLineLeftPoint, topLineRightPoint);
        //    //绘制下边线
        //    graph.DrawLine(pen, bottomLineLeftPoint, bottomLineRightPoint);
        //    //绘制左边线
        //    graph.DrawLine(pen, leftLineTopPoint, leftLineBottomPoint);
        //    //绘制右边线
        //    graph.DrawLine(pen, rightLineTopPoint, rightLineBottomPoint);
        //    Rectangle rectExtends = new Rectangle(topLineLeftPoint.X, topLineLeftPoint.Y, topLineRightPoint.X - topLineLeftPoint.X, leftLineBottomPoint.Y - leftLineTopPoint.Y);
        //    return rectExtends;

        //}
        private Rectangle DrawLineAndArc(Bitmap bitmap, Graphics graph, Rectangle rect,MyEnttitys ents)
        {
            double ratio = rect.Width * 1.0 / rect.Height;

            AcadServices.Extents3d ext = ents.Ents.GetExtents3d();
            
            double width = ext.MaxPoint.X - ext.MinPoint.X;
            double height = ext.MaxPoint.Y - ext.MinPoint.Y;
            Pen pen = new Pen(Brushes.Black);
            
            Rectangle rectExtends; 
            if (width / height >= ratio)
            {
                //以长度占满绘图区域，按比例绘制高度，圆弧
               
                ents.Ents.ScacleEnts(rect.Width * 1.0 / width, new Point3d(ext.MinPoint.X, ext.MaxPoint.Y, 0));
                ext = ents.Ents.GetExtents3d();
                double extHight = ext.MaxPoint.Y-ext.MinPoint.Y;
                ents.Ents.MoveEnts(rect.X, -(rect.Y + (rect.Height - extHight) / 2));
                rectExtends = new Rectangle((int)(rect.X + ext.MinPoint.X), (int)(rect.Y + (rect.Height - extHight) / 2), (int)(ext.MaxPoint.X - ext.MinPoint.X), (int)(ext.MaxPoint.Y - ext.MinPoint.Y));
            }
            else
            {
                //以高度占满绘图区域，按比例绘制长度，圆弧
                width = width * rect.Height / height;
                
                ents.Ents.ScacleEnts(rect.Height * 1.0 / height, new Point3d(ext.MinPoint.X, ext.MaxPoint.Y, 0));
                ext = ents.Ents.GetExtents3d();
                double extWidth = ext.MaxPoint.X - ext.MinPoint.X;
                ents.Ents.MoveEnts(rect.X+(rect.Width-extWidth)/2,-rect.Y);
                rectExtends = new Rectangle((int)(rect.X + (rect.Width - extWidth) / 2), (int)(Math.Abs(ext.MaxPoint.Y) + rect.Y), (int)(ext.MaxPoint.X - ext.MinPoint.X), (int)(ext.MaxPoint.Y - ext.MinPoint.Y));
            }
            
            
            if (ents.Ents.Count > 1)
            {
                //画4条边线
                for (int i = 0; i < 4; i++)
                {
                    if (ents.Ents[i] is AcadServices.Line)
                    {
                        AcadServices.Line line = (AcadServices.Line)ents.Ents[i];
                        Point pt1 = new Point((int)Math.Abs(line.StartPoint.X), (int)Math.Abs(line.StartPoint.Y));
                        Point pt2 = new Point((int)Math.Abs(line.EndPoint.X), (int)Math.Abs(line.EndPoint.Y));
                        graph.DrawLine(pen, pt1, pt2);
                    }
                }
                //画圆弧
                if (ents.Ents.Count >4)
                {
                    for (int i = 4; i < ents.Ents.Count; i++)
                    {
                        Pen penArc = new Pen(Brushes.WhiteSmoke);
                        if (ents.Ents[i] is AcadServices.Arc)
                        {
                            AcadServices.Arc arc = ( AcadServices.Arc)ents.Ents[i];
                            //AcadServices.Extents3d extArc = ents.Ents[i].GeometricExtents;
                            Point center = new Point((int)arc.Center.X, (int)Math.Abs(arc.Center.Y));
                            int radiusArc = (int)arc.Radius;
                            Rectangle rectArc = new Rectangle(center.X-radiusArc,center.Y-radiusArc,radiusArc*2,radiusArc*2);
                            //graph.DrawRectangle(penArc, rectArc);
                            float sweepAngle = (float)(arc.EndAngle-arc.StartAngle).angleToDegree();
                            if (sweepAngle < 0)
                            {
                                sweepAngle += 360;
                            }
                            try
                            {
                                graph.DrawArc(penArc, rectArc, (float)(360 - arc.EndAngle.angleToDegree()), sweepAngle);
                            }
                            catch (Exception)
                            {
                                
                               
                            }
                            
                        }
                    }
                }
            }
            else if (ents.Ents.Count == 1) //如果是圆,则绘制圆
            {
                rectExtends = new Rectangle((int)(rect.X + (rect.Width - rect.Height) / 2), (int)(rect.Y), rect.Height, rect.Height);

                graph.DrawArc(pen, rectExtends, 0, 360);
            }
            
            
            //Rectangle rectExtends = new Rectangle((int)ext.MinPoint.X+rect.X, (int)ext.MaxPoint.Y+rect.Y, (int)(ext.MaxPoint.X - ext.MinPoint.X), (int)(ext.MaxPoint.Y - ext.MinPoint.Y));
            return rectExtends;

        }
        /// <summary>
        /// 绘制注释
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="graph"></param>
        /// <param name="rect"></param>
        private void DrawDimension(Bitmap bitmap, Graphics graph, Rectangle rect,List<AcadServices.Entity> ents)
        {
            int width = picBxDrawMap.Width;
            int height = picBxDrawMap.Height;
            Pen pen = new Pen(Brushes.LawnGreen);
            string strW = numUDlength.Value.ToString();//水平方向的注释文字
            string strH = numUDheight.Value.ToString();//垂直方向的注释文字
            if (rect.Height == rect.Width && numUDRadius.Value != 0 && (numUDRadius.Value * 2 == numUDlength.Value || numUDRadius.Value * 2 == numUDheight.Value))
            {
                strH = strW = "ø " + numUDRadius.Value.ToString();
            }
            //半径的注释文字
            #region //水平长度的注释线
            //Point pointHL1 = new Point(rect.X,(int)(height * 0.05));
            //Point pointHL2 = new Point(rect.X,(int)(height * 0.14));
            Point pointHL1 = new Point(rect.X, (int)(height * 0.05));
            Point pointHL2 = new Point(rect.X, rect.Y - 4);
            Point pointHR1 = new Point(rect.X + rect.Width, (int)(height * 0.05));
            Point pointHR2 = new Point(rect.X + rect.Width, rect.Y - 4);
            Point PointHH1 = new Point(rect.X, (int)(height * 0.08));
            Point PointHH11 = new Point(rect.X + rect.Width / 2 - 12 * (strW.Length / 2) - 6, (int)(height * 0.08));
            Point PointHH2 = new Point(rect.X + rect.Width / 2 + 12 * (strW.Length / 2) + 8, (int)(height * 0.08));
            Point PointHH21 = new Point(rect.X + rect.Width, (int)(height * 0.08));
            graph.DrawString(strW, new Font("宋体", 12), Brushes.LawnGreen, rect.X + rect.Width / 2 - 12 * (strW.Length / 2), (int)(height * 0.08) - 8);
            graph.DrawLine(pen, pointHL1, pointHL2);//水平标注的左侧综线
            graph.DrawLine(pen, pointHR1, pointHR2);//水平标注的左右侧综线
            graph.DrawLine(pen, PointHH1, PointHH11);//第一段水平线
            graph.DrawLine(pen, PointHH2, PointHH21);//第二段水平线
            //左侧箭头
            graph.DrawLine(pen, PointHH1, new Point(PointHH1.X + 12, PointHH1.Y - 3));
            graph.DrawLine(pen, PointHH1, new Point(PointHH1.X + 12, PointHH1.Y + 3));
            //右侧箭头
            graph.DrawLine(pen, PointHH21, new Point(PointHH21.X - 12, PointHH1.Y - 3));
            graph.DrawLine(pen, PointHH21, new Point(PointHH21.X - 12, PointHH1.Y + 3));


            #endregion

            #region  //垂直高度的注释
            Point pointVT1 = new Point((int)(width * 0.05), rect.Y);
            Point pointVT2 = new Point(rect.X - 4, rect.Y);
            graph.DrawLine(pen, pointVT1, pointVT2); //垂直注释上面横线
            Point pointVB1 = new Point((int)(width * 0.05), rect.Y + rect.Height);
            Point pointVB2 = new Point(rect.X - 4, rect.Y + rect.Height);
            graph.DrawLine(pen, pointVB1, pointVB2); //垂直注释下面横线
            graph.DrawString(strH, new Font("宋体", 12), Brushes.LawnGreen, (int)(width * 0.08) - strH.Length * 10 / 2, rect.Y + rect.Height / 2 - 8);//垂直方向的注释文字
            Point pointVV1 = new Point((int)(width * 0.08), rect.Y);
            Point pointVV11 = new Point((int)(width * 0.08), rect.Y + rect.Height / 2 - 8);
            Point pointVV2 = new Point((int)(width * 0.08), rect.Y + rect.Height / 2 + 8);
            Point pointVV21 = new Point((int)(width * 0.08), rect.Y + rect.Height);
            graph.DrawLine(pen, pointVV1, pointVV11); //垂直注释第一段线
            graph.DrawLine(pen, pointVV2, pointVV21); //垂直注释第二段线
            //上面箭头
            graph.DrawLine(pen, pointVV1, new Point(pointVV1.X - 3, pointVV1.Y + 12));
            graph.DrawLine(pen, pointVV1, new Point(pointVV1.X + 3, pointVV1.Y + 12));
            //下面箭头
            graph.DrawLine(pen, pointVV21, new Point(pointVV21.X - 3, pointVV21.Y - 12));
            graph.DrawLine(pen, pointVV21, new Point(pointVV21.X + 3, pointVV21.Y - 12));
            #endregion

            //半径注释

            if (ents.Count > 4)
            {
                for (int i = 4; i < ents.Count; i++)
                {
                    if (ents[i] is AcadServices.Arc)
                    {
                        AcadServices.Arc arc = (AcadServices.Arc)ents[i];
                        Point lineEnd = new Point((int)arc.Center.X,(int)Math.Abs(arc.Center.Y));
                        Point3d onArcPoint = new Point3d();
                        //画斜线
                        if (arc.EndAngle - arc.StartAngle < 0)
                        {
                            onArcPoint = arc.Center.PolarPoint((arc.StartAngle + arc.EndAngle + Math.PI*2) / 2, arc.Radius * 0.95);
                        }
                        else
                        {
                            onArcPoint = arc.Center.PolarPoint((arc.StartAngle + arc.EndAngle) / 2, arc.Radius * 0.95);
                        }
                       
                        Point lineStart = new Point((int)Math.Abs(onArcPoint.X) , (int)Math.Abs(onArcPoint.Y));
                        //Point lineStart = new Point(lineEnd.X, (int)(lineEnd.Y + arc.Radius));
                        graph.DrawLine(pen, lineStart, lineEnd);

                        //画条直线
                        Point pointText;
                        if (lineStart.X < lineEnd.X)
                        {
                            pointText = new Point((int)(lineEnd.X + arc.Radius * 0.4), lineEnd.Y);
                        }
                        else
                        {
                            pointText = new Point((int)(lineEnd.X - arc.Radius * 0.6), lineEnd.Y);
                        }
                        graph.DrawLine(pen, pointText, lineEnd);
                        //画半径大小
                        Point pointTexton ;
                        string strR = "R " + numUDRadius.Value.ToString() ;
                        if (lineStart.Y > lineEnd.Y) //3 4 象限
                        {
                            pointTexton = new Point(0,lineEnd.Y + 2);
                        }
                        else // 1 2 象限
                        {
                            pointTexton = new Point(0, lineEnd.Y -16);
                        }
                        if (lineStart.X < lineEnd.X) //2 3 象限
                        {
                            pointTexton.X = (int)((lineEnd.X + pointText.X) / 2 + strR.Length * 5);
                        }
                        else // 1 4 象限
                        {
                            pointTexton.X = (int)((lineEnd.X + pointText.X) / 2 - strR.Length * 10);
                        }
                        
                        graph.DrawString(strR, new Font("宋体", 12), Brushes.LawnGreen,pointTexton.X,pointTexton.Y);

                        //画箭头 圆弧标注的箭头
                        Point p1;
                        Point p2;
                        if (arc.EndAngle - arc.StartAngle < 0)
                        {
                            
                            double angle = 15;
                            Point3d p = onArcPoint.PolarPoint(Math.PI + (arc.StartAngle + arc.EndAngle + Math.PI * 2) / 2 - angle.degreeToAngle(),arc.Radius *0.2);
                            p1 = new Point((int)p.X, (int)Math.Abs(p.Y));
                            p = onArcPoint.PolarPoint(Math.PI + (arc.StartAngle + arc.EndAngle + Math.PI * 2) / 2 + angle.degreeToAngle(), arc.Radius * 0.2);
                            p2 = new Point((int)p.X, (int)Math.Abs(p.Y));
                        }
                        else
                        {
                            double angle = 15;
                            Point3d p = onArcPoint.PolarPoint(Math.PI + (arc.StartAngle + arc.EndAngle ) / 2 - angle.degreeToAngle(), arc.Radius * 0.2);
                            p1 = new Point((int)p.X, (int)Math.Abs(p.Y));
                            p = onArcPoint.PolarPoint(Math.PI + (arc.StartAngle + arc.EndAngle) / 2 + angle.degreeToAngle(), arc.Radius * 0.2);
                            p2 = new Point((int)p.X, (int)Math.Abs(p.Y));
                        }
                        graph.DrawLine(pen, lineStart, p1);
                        graph.DrawLine(pen, lineStart, p2);
                    }
                    
                }
            }

            //绘制中心线
            #region
            double lengthDiv = (rect.Height + 10) / 39;
            Point firstPoint = new Point(rect.X + rect.Width / 2, rect.Y - 5);
            Point endPoint = new Point((int)(rect.X + rect.Width / 2), (int)(firstPoint.Y + 2 * lengthDiv));
            for (int i = 0; i < 20; i++)
            {
                graph.DrawLine(new Pen(Brushes.PaleVioletRed), firstPoint, endPoint);
                firstPoint.Y = endPoint.Y + (int)lengthDiv;
                endPoint = new Point((int)(rect.X + rect.Width / 2), (int)(firstPoint.Y + 2 * lengthDiv));
            }

            lengthDiv = (rect.Width + 10) / 39;
            firstPoint = new Point((int)(rect.X - 5), (int)(rect.Y + rect.Height / 2));
            endPoint = new Point((int)(firstPoint.X + lengthDiv), (int)(rect.Y + rect.Height / 2));
            for (int i = 0; i < 22; i++)
            {
                graph.DrawLine(new Pen(Brushes.PaleVioletRed), firstPoint, endPoint);
                firstPoint.X = endPoint.X + (int)lengthDiv;
                endPoint = new Point((int)(firstPoint.X + lengthDiv), (int)(rect.Y + rect.Height / 2));
            }
            #endregion



        }

        private void numUDlength_ValueChanged(object sender, EventArgs e)
        {
            if (numUDlength.Value <= numUDRadius.Value *2)
            {
                numUDRadius.Value = (int)(numUDlength.Value / 2);
            }
            this.DrawEentity();
        }

        private void numUDheight_ValueChanged(object sender, EventArgs e)
        {
            if (numUDheight.Value <= numUDRadius.Value * 2)
            {
                numUDRadius.Value = (int)(numUDheight.Value / 2);
            }
            this.DrawEentity();
        }

        private void btnDrawToCAD_Click(object sender, EventArgs e)
        {
            MyEnttitys ents = new MyEnttitys((double)numUDlength.Value, (double)numUDheight.Value, (double)numUDRadius.Value);
            //获取图形的基点
            AcadServices.Extents3d ext = ents.Ents.GetExtents3d();
            double X = (double)numUDX.Value;
            double Y = (double)numUDY.Value;
            ents.Ents.MoveEnts(X - ext.MinPoint.X, Y - (ext.MinPoint.Y + ext.MaxPoint.Y) / 2);
            DatabaseTool.AddEntiy(ents.Ents);
            this.Dispose();
        }

        private void numUDRadius_ValueChanged(object sender, EventArgs e)
        {
            if (numUDRadius.Value * 2 >= numUDlength.Value || numUDRadius.Value * 2>numUDheight.Value)
            {
                numUDRadius.Value = numUDlength.Value > numUDheight.Value ? (int)(numUDheight.Value / 2) : (int)(numUDlength.Value / 2);
            }
            this.DrawEentity();
        }
        /// <summary>
        /// 在屏幕空间选择坐标点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPick_Click(object sender, EventArgs e)
        {
            this.Hide();
            PromptPointResult ppr = DatabaseTool.PickPointONScreen();
            if (ppr.Status == PromptStatus.OK)
            {
                numUDX.Value =(decimal) ppr.Value.X;
                numUDY.Value = (decimal)ppr.Value.Y;
            }
            this.Show();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

       
    }
}
